package cn.wolfcode.luowowo.member.service.impl;

import cn.wolfcode.luowowo.cache.service.IUserInfoRedisService;
import cn.wolfcode.luowowo.cache.service.IVerifyCodeRedisService;
import cn.wolfcode.luowowo.common.exception.DisableException;
import cn.wolfcode.luowowo.common.util.AssertUtil;
import cn.wolfcode.luowowo.common.util.StringUtil;
import cn.wolfcode.luowowo.member.domain.UserInfo;
import cn.wolfcode.luowowo.member.mapper.UserInfoMapper;
import cn.wolfcode.luowowo.member.service.IUserInfoService;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StreamUtils;

import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by Administrator on 2019/7/5.
 */
@Service
public class UserInfoServiceImpl implements IUserInfoService {
    @Autowired
    private UserInfoMapper userInfoMapper;

    @Reference
    private IVerifyCodeRedisService verifyCodeRedisService;

    @Reference
    private IUserInfoRedisService userInfoRedisService;

    @Override
    public UserInfo get(Long id) {
        return userInfoMapper.selectByPrimaryKey(id);
    }

    @Override
     public boolean checkPhone(String phone) throws DisableException {
        //为了防止有人通过url传手机号码过来,需要在后台再次校验手机号是否为空
        if (StringUtil.notHasLength(phone)) {
            throw new DisableException("手机号不能为空!");
        }
        String regex = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17[013678])|(18[0,5-9]))\\d{8}$";
        if (phone.length() != 11) {
            throw new DisableException("手机号码尾数应该为11位!");
        } else {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(phone);
            boolean isMatch = m.matches();
            if (!isMatch) {
                throw new DisableException("手机号码格式不对!");
            }
        }
        //正则校验
        return userInfoMapper.selectByPhone(phone) > 0;
    }

    @Override
    public void userRegist(String phone, String nickname, String password, String rpassword, String verifyCode) throws DisableException {
        //判断各个参数是否为空
        AssertUtil.isNull(phone, "手机号码不能为空");
        AssertUtil.isNull(nickname, "昵称不能为空");
        AssertUtil.isNull(password, "密码不能为空");
        AssertUtil.isNull(rpassword, "确认密码不能为空");
        AssertUtil.isNull(verifyCode, "验证码不能为空");
        AssertUtil.isEquals(password, rpassword, "两次密码输入不一致");
        //判断手机是否唯一
        if (checkPhone(phone)) {
            throw new DisableException("手机号码已经注册!");
        }
        //判断验证码是否一致
        //这里验证码是否一致,我们单独抽取一个方法,叫checkVerifyCode
        checkVerifyCode(phone,verifyCode);

        //注册
        UserInfo userInfo = new UserInfo();
        userInfo.setPhone(phone);
        userInfo.setNickname(nickname);
        userInfo.setPassword(password);
        userInfo.setLevel(1);
        userInfo.setState(UserInfo.STATE_NORMAL);//设置默认状态为普通
        userInfo.setHeadImgUrl("/images/default.jpg");
        userInfoMapper.insert(userInfo);
    }

    public void checkVerifyCode(String phone,String verifyCode) {
        //从redis中查到验证码跟目前的验证码进行比较
        String redisVerifyCode = verifyCodeRedisService.get(phone);
        System.out.println(redisVerifyCode);
        System.out.println(verifyCode);
        //如果两个验证码不相等,那么就抛出异常
        if (!verifyCode.equalsIgnoreCase(redisVerifyCode)){
            throw new DisableException("请输入正确的验证码");
        }
    }

    @Override
    public void sendVerifyCode(String phone) throws DisableException{
        //假如已经进行手机号码校验
        //1.生成4位验证码
        String verifyCode = UUID.randomUUID().toString().substring(0, 4);
        //2.发送到用户手机
        StringBuilder sb = new StringBuilder(80);
        sb.append("【创信】你的验证码是：").append(verifyCode).append(",3分钟内有效");
        //假装发送到控制台就是发送到手机上了
        System.out.println(sb.toString());
        try {
            sendMsg(phone,sb.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //3.缓存
        verifyCodeRedisService.saveVerifyCode(phone,verifyCode);
    }

    @Value("${msg.url}")
    private String msgUrl;
    @Value("${msg.appkey}")
    private String appkey;
    private void sendMsg(String phone, String content) throws Exception{
        URL url = new URL(msgUrl );
        //建立连接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        //设置请求方法
        connection.setRequestMethod("GET");
        //设置请求参数
        StringBuilder sb = new StringBuilder(100);


        sb.append("phone=").append(phone)
                .append("&content=").append(content).append("&appkey=").append(appkey);

        //默认是false， 设置true表示输出参数
        connection.setDoOutput(true);
        connection.getOutputStream().write(sb.toString().getBytes("UTF-8"));
        //请求连接
        connection.connect();
        //获取响应数据
        String resp = StreamUtils.copyToString(connection.getInputStream(), Charset.forName("UTF-8"));
        System.out.println(resp);
    }

    @Override
    public String checkLogin(String username, String password) throws DisableException{
        //这里去数据库查询,是否有该账户的存在,如果有,那么就将该用户保存在redis中,
        UserInfo userInfo= userInfoMapper.selectByUsernameAndPassowrd(username,password);
        //如果userInfo对象不为空,那么就将其保存到redis中
        if(userInfo==null){
            throw new DisableException("账号或者密码错误!");
        }
        //如果该对象不为空,那么将该对象存入redis中
        //key:前缀+UUid的随机数(随机数中去掉"-")
        //value:UserInfo对象
        String uuidStr = UUID.randomUUID().toString().replace("-","");
        userInfoRedisService.saveUserInfo(uuidStr,userInfo);
        return uuidStr;
    }

    @Override
    public List<UserInfo> list() {
        return userInfoMapper.selectAll();
    }
}
